package main

import (
	"context"
	"fmt"
	"google.golang.org/grpc"
	"io"
	"log"
	"net"
	pb "protoc-demo02/proto"
)

type server struct {
	// 这个必须引入UnimplementedSumServiceServer
	// 及时没有实现接口的方法也不会报错
	pb.UnimplementedSumServiceServer
}

// Sum 这个函数其实就是我们在proto文件中定义的rpc函数
// 如果不清楚具体参数可以到sum_grpc.pb.go文件中查看
func (s *server) Sum(ctx context.Context, in *pb.SumRequest) (*pb.SumResponse, error) {
	// 这里的SumRequest和SumResponse就是我们在proto文件中定义的message类型
	// 只是变量名变成了首字母大写的驼峰命名法
	return &pb.SumResponse{Result: in.A + in.B}, nil
}

func (s *server) Subtract(ctx context.Context, in *pb.SubtractRequest) (*pb.SubtractResponse, error) {
	// 只是变量名变成了首字母大写的驼峰命名法
	return &pb.SubtractResponse{Result: in.A - in.B}, nil
}

// Factors 流的响应，没有返回值 —— 流是在过程中Send的，所以没有返回值
// 流在入参中
func (s *server) Factors(req *pb.FactorsRequest, stream pb.SumService_FactorsServer) error {
	for i := 1; i <= int(req.Num); i++ {
		if int(req.Num)%i == 0 {
			fmt.Println("----------,", i)
			// 这里Send发送流数据
			if err := stream.Send(&pb.FactorsResponse{Factor: int32(i)}); err != nil {
				return err
			}
		}
	}
	return nil
}

// SumStream 流的请求，也没有返回值 —— 在Recv完后，SendAndClose发送响应
func (s *server) SumStream(stream pb.SumService_SumStreamServer) error {
	sum := 0
	for {
		req, err := stream.Recv()
		// 通过io.EOF判断是否是流结束
		if err == io.EOF {
			// 结束后返回响应
			return stream.SendAndClose(&pb.SumStreamResponse{Sum: int32(sum)})
		}
		if err != nil {
			return err
		}
		sum += int(req.Num)
	}
}

// https://juejin.cn/post/7375386125814546470#heading-13

func main() {
	lis, err := net.Listen("tcp", ":50051")
	if err != nil {
		log.Fatalf("failed to listen:%v", err)
	}
	s := grpc.NewServer()
	// 注册服务
	pb.RegisterSumServiceServer(s, &server{})
	fmt.Printf("server started at %s\n", lis.Addr())
	if err := s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}
